#include<iostream>
#include<ctime>
#include<algorithm>
using namespace std;
/*
   日期类：
    重载+: 实现日期+days
 重载-: 实现日期-days 日期-日期
 重载++: 实现日期前置++
 重载--: 实现日期前置--
*/
class date {
protected:
    int _year;
    int _month;
    int _day;//保护乘员
public:
    void SetYear(int year) { _year = year; }
    void SetMonth(int month) { _month = month; }
    void SetDay(int day) { _day = day; }
    date(int year = 1700, int month = 1, int day = 1) {
        _year = year;
        _month = month;
        _day = day;
    }//重载默认值构造函数
    date(date& d) {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }//拷贝构造函数
    int leap_year(int now_year) { //判断闰年 是闰年返回1 否则返回0
        if ((now_year % 4 == 0 && now_year % 100 != 0) || (now_year % 400 == 0)) {
            return 1;
        }
        return 0;
    }
    friend ostream& operator<<(ostream& out, date& d) {
        out << d._year << "-" << d._month << "-" << d._day;
        out << endl;
        return out;
    }//用于输出日期
    friend istream& operator>>(istream& in, date& d) {
        int year, month, day;
        cout << "请输入正确的年-月-日" << endl;
        cin >> year >> month >> day;
        d.SetYear(year); d.SetMonth(month);
        d.SetDay(day);
        return in;
    }//用于输入日期
    date& operator=(date& d) {
        _year = d._year;
        _month = d._month;
        _day = d._year;
    }//赋值构造函数
    date& operator+(int n) { //加上n天 n可能负数 可能加到下一年 可能加几年
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(this->_year)) { //如果是闰年 1990 3 1 + 1000
            months[1] = 29;
        }
        int n_cor = abs(n);
        this->_day += n_cor;
        //一个循环搞定
        while (this->_day > months[this->_month - 1]) {
            this->_day -= months[this->_month - 1];
            this->_month += 1;
            if (this->_month > 12) { //超过一年了
                this->_month = 1;
                this->_year += 1;
                if (leap_year(this->_year)) {
                    months[1] = 29;
                }
                else {
                    months[1] = 28;
                }
            }
        }
        return *this;
    }//重载+运算符
    date& operator-(int n) { //减去n天 n可能为负数 n可能减到前一年 n可能减几年
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(this->_year)) {
            months[1] = 29;
        }
        int n_cor = abs(n);
        this->_day = this->_day - n_cor;
        //一个循环搞定
        while (this->_day <= 0) {
            this->_month -= 1;
            if (this->_month <= 0) {
                this->_year -= 1;
                if (leap_year(this->_year)) {
                    months[1] = 29;
                }
                else {
                    months[1] = 28;
                }
                this->_month = 12;
            }
            this->_day = this->_day + months[this->_month - 1];
        }
        return *this;
    }//重载减运算符
    date& operator++() {
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(this->_year)) {
            months[1] = 29;
        }
        this->_day++;
        if (this->_day > months[this->_month - 1]) {
            this->_day = this->_day - months[this->_month - 1];
            this->_month += 1;
            if (this->_month > 12) {
                this->_month = 1;
                this->_year++;
            }
        }
        return *this;
    }//重载前置++运算符;
    date& operator--() {
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(this->_year)) {
            months[1] = 29;
        }
        this->_day -= 1;
        if (this->_day <= 0) {
            this->_day = this->_day + months[this->_month - 1];
            this->_month -= 1;
            if (this->_month <= 0) {
                this->_month = 12;
                this->_year -= 1;
            }
        }
        return *this;
    }//重载前置--运算符
    int operator-(date& d) {
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(min(this->_year, d._year))) {
            months[1] = 29;
        }
        int d_days = d._day;
        int this_days = this->_day;
        if (this->_year != d._year) { //二者不在同一年
            int min_year = min(this->_year, d._year);//获得二者小的年份
            int now_year;
            for (now_year = min_year; now_year < this->_year; now_year++) {
                this_days += 365 + leap_year(now_year);
            }
            for (int m = 1; m < this->_month; m++) {
                this_days += months[m];
            }//计算this_days的值
            for (now_year = min_year; now_year < d._year; now_year++) {
                d_days += 365 + leap_year(now_year);
            }
            for (int m = 1; m < d._month; m++) {
                d_days += months[m];
            }
        }
        else { //在同一年
            for (int m = 1; m < this->_month; m++) {
                this_days += months[m];
            }
            for (int m = 1; m < d._month; m++) {
                d_days += months[m];
            }
        }
        return abs(d_days - this_days);
    }//重载-运算符 计算两日期相差的天数
    ~date() { }//析构函数
};
/*
    时间类：
    继承date 增加时分秒
 可实现和日期相同的功能,支持分钟加减。
*/
class Time :public date {
private:
    int _hour;
    int _minute;
    int _second;
public:
    Time(int year, int month, int day, int hour = 1, int min = 1, int second = 1) :
        date(year, month, day), _hour(hour), _minute(min), _second(second) {}
    void outtime() {
        cout << "该时间为：" << endl;
        cout << _year << "-" << _month << "-" << _day << "-" << _hour << "-" << _minute << "-"
            << _second;
        cout << endl;
    }//输出函数
    Time& Addmin(int minutes) { //加minutes分钟
        int summin = this->_minute, nowhours = this->_hour, adddays = 0;//初始化
        summin = this->_minute + minutes;//分单位总共有多少分钟
        nowhours = this->_hour + summin / 60;//小时单位总共有多少小时
        adddays = nowhours / 24;//小时单位将会产生几天的进位
        (*this) + adddays;//直接+adddays;
        this->_minute = summin % 60;
        this->_hour = nowhours % 24;
        //返回时间
        return *this;
    }//时间加分钟
    Time& Adds(int s) { //加minutes分钟
        int sums = this->_second, summin = this->_minute, nowhours = this->_hour, adddays = 0;//初始化
        sums = this->_second + s;
        summin = this->_minute + sums/60;//分单位总共有多少分钟
        nowhours = this->_hour + summin / 60;//小时单位总共有多少小时
        adddays = nowhours / 24;//小时单位将会产生几天的进位
        (*this) + adddays;//直接+adddays;
        this->_second = sums % 60;
        this->_minute = summin % 60;
        this->_hour = nowhours % 24;
        //返回时间
        return *this;
    }//时间加分钟
    Time& Submin(int minutes) {
        this->_minute = this->_minute - minutes;
        while (this->_minute < 0) {
            this->_hour = this->_hour - 1;
            this->_minute += 60;
            if (this->_hour <= 0) {
                this->_hour = 24;
                (*this) - 1;
            }
        }
        return *this;
    }//时间减分钟
    long long  interval(Time& t) {
        int months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
        if (leap_year(min(this->_year, t._year))) {
            months[1] = 29;
        }
        int min_year = min(t._year, this->_year);
        int this_days = this->_day, t_days = t._day;
        for (int now_year = min_year; now_year < this->_year; now_year++) {
            this_days += 365 + leap_year(now_year);
        }
        for (int m = 1; m < this->_month; m++) {
            this_days += months[m - 1];
        }//计算this_days的值
        for (int now_year = min_year; now_year < t._year; now_year++) {
            t_days += 365 + leap_year(now_year);
        }
        for (int m = 1; m < t._month; m++) {
            t_days += months[m - 1];
        }
        long long this_seconds = this_days * 24 * 3600 + this->_hour * 3600 + this->_minute * 60 + this->_second;
        long long  t_seconds = t_days * 24 * 3600 + t._hour * 3600 + t._minute * 60 + t._second;
        long long interva = abs(this_seconds - t_seconds);
        return interva;
    }//计算时间间隔 返回秒
    ~Time() { }//析构函数
};
int main() {

Time t1(2020, 6, 4, 20, 22, 15);
    t1.outtime();
    t1.Adds(1);
    cout << "t1时间加1470分钟后";//测试加分钟
    t1.outtime();

}